package com.feihong.yw189.utils.facetools;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.text.format.DateFormat;
import android.util.Base64;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.feihong.yw189.app.App;
import com.feihong.yw189.listener.http.RequestCallBack;
import com.feihong.yw189.model.Kaika.UpLoadPicModel;
import com.feihong.yw189.utils.CatchFileUtils;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import org.apache.http.Header;
import org.json.JSONObject;
import org.xutils.common.Callback;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * Created by Sabirjan on 2017/7/5.
 * TXGWApp.
 * 飞宏电子
 * 人脸图片上传并 face验证
 */

public class UploadAndVerifyFace extends Thread {

    private static final String TAG = "活体检测";
    private static final String VERIFY_URL = "https://api.megvii.com/faceid/v2/verify";


    private UploadCallBack callBack;
    private Context mContext;
    private Bitmap bitmap = null;//上传的最好的人脸图片  【活体检测返回】
    private String cardImage = "";//身份证的Base64图片
    private String delta = "";//活体检测返回的信息 【活体检测返回】
    private Map<String, byte[]> images = new HashMap<>();//  【活体检测返回】
    private File personFile;//活体检测本地保存的照片
    private String uploadFileUrl = "";//上传的图片地址
    private String cardID = "";//身份证号码

    private String faceMessage = "";
    private String headPath;

    public UploadAndVerifyFace(Context context, String headPath, UploadCallBack callBack) {
        this.mContext = context;
        this.callBack = callBack;
        this.headPath = headPath;
        Log.e("项目异常", "---saveIDIcon---headPath------" + headPath);
    }

    /**
     * 初始化 数据
     *
     * @param facebitmap 人脸图片  【活体检测返回】
     * @param cardImage  身份证的Base64图片
     * @param cardID     身份证号码
     * @param delta      活体检测返回的信息 【活体检测返回】
     * @param images     活体检测返回图片【活体检测返回】
     */
    public void initData(Bitmap facebitmap, String cardImage, String cardID, String delta, Map<String, byte[]> images) {
        this.bitmap = facebitmap;
        this.cardImage = cardImage;
        this.delta = delta;
        this.images = images;
        this.cardID = cardID;
    }

    public void setFaceBitmap(Bitmap facebitmap) {
        this.bitmap = facebitmap;
    }

    public void setCardID(String cardID) {
        this.cardID = cardID;
    }

    public void setCardImage(String cardImage) {
        this.cardImage = cardImage;
    }

    public void setDelta(String delta) {
        this.delta = delta;
    }

    public void setImages(Map<String, byte[]> images) {
        this.images = images;
    }

    /**
     * 开始上传
     */
    public void startUpload() {
        Message message = new Message();
        if (this.bitmap == null) {
            message.what = -1;
            message.obj = "上传的文件对象不能为空！";
            mHanlder.sendMessage(message);
            return;
        }
//        if (this.cardImage == null || this.cardImage.trim().length() == 0) {
//            message.what = -1;
//            message.obj = "身份证图片不能为空！";
//            mHanlder.sendMessage(message);
//            return;
//        }
        if (this.delta == null || this.delta.trim().length() == 0) {
            message.what = -1;
            message.obj = "活体检测校验码不能为空！";
            mHanlder.sendMessage(message);
            return;
        }
        if (this.cardID == null || this.cardID.trim().length() < 15) {
            message.what = -1;
            message.obj = "身份证号码有误";
            mHanlder.sendMessage(message);
            return;
        }
        if (this.images == null || this.images.size() == 0) {
            message.what = -1;
            message.obj = "活体检测图片集合不能为空！";
            mHanlder.sendMessage(message);
            return;
        }
        this.start();
    }

    Handler mHanlder = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what > 0) {

                if (msg.what == 100) {
                    if (callBack != null) {
                        callBack.success(uploadFileUrl, 1, faceMessage);
                    }
                } else {
                    if (callBack != null) {
                        callBack.success(uploadFileUrl, -1, faceMessage);
                    }
                }
            } else {
                if (callBack != null) {
                    callBack.error(msg.obj.toString());
                }
            }
        }
    };


    @Override
    public void run() {
        final Message message = new Message();
        String name = DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
        FileOutputStream b = null;
        File file = new File(App.getApp().getApplication().getCacheDir() + "/yw189imgae/");
        file.mkdirs();
        String faceIMG = App.getApp().getApplication().getCacheDir() + "/yw189imgae/" + name;
        try {
            b = new FileOutputStream(faceIMG);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);
            String facePhotoPath = new File(faceIMG).getPath();
            uploadFaceBest(message, new File(facePhotoPath));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            message.what = -1;
            message.obj = "上传图片失败\n" + e.toString();
            mHanlder.sendMessage(message);
        }
    }

    private void uploadFaceBest(final Message message, File file) {
        App.getApp().getHttpTools().uploadFile(file, new RequestCallBack<String>() {

            @Override
            public void onSuccess(String result) {
                Log.e(TAG, "uploadFaceBest:------" + result);
                try {
                    UpLoadPicModel upLoadPicModel = JSON.parseObject(result, UpLoadPicModel.class);
                    if (upLoadPicModel.getStatus() == 1) {
                        uploadFileUrl = upLoadPicModel.getData().getUrl();
//                        zhengMianUrlRep = upLoadPicModel.getData().getUrl_rep();

                        compaerFace(message);
                    } else {
                        message.what = -1;
                        message.obj = "上传图片失败\n" + upLoadPicModel.getInfo();
                        mHanlder.sendMessage(message);
                    }
                } catch (Exception e) {
                    message.what = -1;
                    message.obj = "上传图片失败\n" + e.toString();
                    mHanlder.sendMessage(message);
                }

            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                Log.e("项目异常", "------onError网络或服务器错误------" + ex.toString());
                message.what = -1;
                message.obj = "网络或服务器错误";
                mHanlder.sendMessage(message);
                return;
            }

            @Override
            public void onCancelled(Callback.CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }
        });
    }

    private void compaerFace(Message message) {
        try {
            RequestParams requestParams = new RequestParams();
            requestParams.put("uuid", cardID);
            byte[] bytes;
            bytes = Base64.decode(headPath, Base64.NO_WRAP);

            try {
                OutputStream outputStream = mContext.openFileOutput(CatchFileUtils.Person_IMAGE_NAME, Context.MODE_PRIVATE);
                outputStream.write(bytes);
                outputStream.flush();
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            File file = new File(mContext.getFilesDir(), CatchFileUtils.Person_IMAGE_NAME);
            // 传入身份证头像照片路径
            requestParams.put("image_ref1", new FileInputStream(file));

            requestParams.put("delta", delta);
            requestParams.put("api_key", "iOzZNlHB2fsz_Bj_3_C2GN5vOdLIoNBc");
            requestParams.put("api_secret", "G3Dliy_up17PCxP6Z_sc3VTlNQSl7v_X");
            requestParams.put("comparison_type", 0 + "");
            requestParams.put("face_image_type", "meglive");

            for (Map.Entry<String, byte[]> entry : images.entrySet()) {
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(entry.getValue());
                requestParams.put(entry.getKey(), byteArrayInputStream);
            }
            AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
            asyncHttpClient.post(VERIFY_URL, requestParams,
                    new AsyncHttpResponseHandler() {
                        @Override
                        public void onSuccess(int i, Header[] headers, byte[] bytes) {
                            try {


                                file.delete();
                                String verify_result = new String(bytes);
                                Log.e(TAG, "verify_result: " + verify_result);
                                JSONObject object = null;
                                object = new JSONObject(verify_result);

                                if (verify_result == null || verify_result.contains("error_message")) {
                                    throw new Exception("验证失败！");
                                }
                                JSONObject jObject = object
                                        .getJSONObject("result_ref1");
                                double idcard_confidence = jObject
                                        .getDouble("confidence");
                                double idcard_tenThreshold = jObject
                                        .getJSONObject("thresholds")
                                        .getDouble("1e-4");
                                // 解析faceGen
                                JSONObject jObject1 = object
                                        .getJSONObject("face_genuineness");

                                float mask_confidence = (float) jObject1
                                        .getDouble("mask_confidence");
                                float mask_threshold = (float) jObject1
                                        .getDouble("mask_threshold");
                                float screen_replay_confidence = (float) jObject1
                                        .getDouble("screen_replay_confidence");
                                float screen_replay_threshold = (float) jObject1
                                        .getDouble("screen_replay_threshold");

                                float synthetic_face_confidence = (float) jObject1
                                        .getDouble("synthetic_face_confidence");
                                float synthetic_face_threshold = (float) jObject1
                                        .getDouble("synthetic_face_threshold");
                                int face_replaced = jObject1.getInt("face_replaced");

                                if (mask_confidence >= 0.2) {
                                    //"面具攻击，识别不通过！"
                                    faceMessage = "面具攻击，识别不通过！";
                                } else if (screen_replay_confidence >= 0.2) {
                                    // "屏幕翻拍，识别不通过！"
                                    faceMessage = "屏幕翻拍，识别不通过！";
                                } else if (synthetic_face_confidence >= 0.2) {
                                    //"软件合成，识别不通过！"
                                    faceMessage = "软件合成，识别不通过！";
                                } else if (face_replaced == 1) { // 0表示未检测出换脸攻击，1表示检测出了换脸攻击
                                    //检测出了换脸攻击
                                    faceMessage = "检测出了换脸攻击";
                                } else {
                                    if (idcard_confidence >= idcard_tenThreshold) {
                                        //
                                        faceMessage = "成功";
                                        mHanlder.sendEmptyMessage(100);
                                        return;
                                    } else {
                                        //"识别未通过，请重新验证！"
                                        faceMessage = "识别未通过，请重新验证！";
                                    }
                                }
                                mHanlder.sendEmptyMessage(88);
                            } catch (Exception e) {
                                e.printStackTrace();
                                faceMessage = "数据解析异常22:" + e.toString();
                                mHanlder.sendEmptyMessage(88);
                            }
                        }

                        @Override
                        public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
                            file.delete();
                            faceMessage = "对比失败网络或服务器错误";
                            mHanlder.sendEmptyMessage(88);
                        }
                    });


        } catch (Exception ex) {
            ex.printStackTrace();
            message.what = -1;
            message.obj = "验证失败 \n" + ex.getMessage();
            mHanlder.sendMessage(message);
            return;
        }
    }
}
